package com.leo.chapter12;

import org.junit.Assert;
import org.junit.Test;

/**
 *
 * @author xuexiaolei
 * @version 2017年10月19日
 */
public class BoundedBufferTest {

    /**
     * 基本的单元测试
     */
    @Test
    public void testIsEmptyWhenCounstructed(){
        BoundedBuffer<Integer> bb = new BoundedBuffer<>(10);
        Assert.assertTrue(bb.isEmpty());
        Assert.assertFalse(bb.isFull());
    }

    /**
     * 基本的单元测试
     */
    @Test
    public void testIsFullAfterPuts() throws InterruptedException {
        BoundedBuffer<Integer> bb = new BoundedBuffer<>(10);
        for (int i = 0; i < 10; i++) {
            bb.put(i);
        }
        Assert.assertTrue(bb.isFull());
        Assert.assertFalse(bb.isEmpty());
    }

    /**
     * 对阻塞操作的测试
     */
    @Test
    public void testTakeBlocksWhenEmpty(){
        final BoundedBuffer<Integer> bb = new BoundedBuffer<>(10);
        Thread taker = new Thread(){
            @Override public void run(){
                try {
                    int unused = bb.take();
                    Assert.fail();
                } catch (InterruptedException e) {
                }
            }
        };
        try {
            taker.start();
            Thread.sleep(100);
            taker.interrupt();
            taker.join(100);
            Assert.assertFalse(taker.isAlive());
        } catch (InterruptedException e) {
            Assert.fail();
        }
    }

    /**
     * 适合测试用的随机数生成器,y可以用nanoTime
     * @param y
     * @return
     */
    static int xorShift(int y){
        y ^= y<<6 ;
        y ^= y>>>21 ;
        y ^= y<<7 ;
        return y;
    }
}
